package com.uziot.bucket.sequence.service;

import com.alibaba.druid.pool.DruidDataSource;
import com.uziot.bucket.sequence.dao.domain.Sequences;
import com.uziot.bucket.sequence.dao.mapper.OracleSequenceMapper;
import com.uziot.bucket.sequence.exception.SequencesAlreadyExistsException;
import com.uziot.bucket.sequence.exception.SequencesNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;

/**
 * @author shidt
 * @version V1.0
 * @className OracleSequenceService
 * @date 2021-01-08 23:33:22
 * @description
 */
@Service
public class OracleSequenceService {
    @Resource
    private OracleSequenceMapper oracleSequenceMapper;

    @Resource
    private DataSource dataSource;

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void createSeq(Sequences sequences) {
        // durid有防注入，不能设置cache
        try {
            oracleSequenceMapper.create(sequences);
        } catch (Throwable t) {
            // oracle ora-00955 序列名称已定义
            if (t.getCause() instanceof SQLException &&
                    ((SQLException) t.getCause()).getErrorCode() == 955) {
                throw new SequencesAlreadyExistsException(sequences.getSeqName());
            }
            throw t;
        }
    }

    /**
     * 获取序列
     *
     * @param seq seq
     * @return Long
     */
    public Long getSeq(Sequences seq) {
        try {
            return oracleSequenceMapper.getSeq(seq);
        } catch (Throwable t) {
            // oracle ora-02289 序列不存在
            if (t.getCause() instanceof SQLException &&
                    ((SQLException) t.getCause()).getErrorCode() == 2289) {
                throw new SequencesNotFoundException(seq.getSeqName());
            }
            throw t;
        }
    }

    /**
     * 获取一个序列集合
     *
     * @param seq seq
     * @return List
     */
    public List<Long> getSeqList(Sequences seq) {
        try {
            return oracleSequenceMapper.getSeqList(seq);
        } catch (Throwable t) {
            // oracle ora-02289 序列不存在
            if (t.getCause() instanceof SQLException &&
                    ((SQLException) t.getCause()).getErrorCode() == 2289) {
                throw new SequencesNotFoundException(seq.getSeqName());
            }
            throw t;
        }
    }

    /**
     * 是否含有序列
     *
     * @param seqName seqName
     * @return boolean
     */
    public boolean containsSequence(String seqName) {
        Sequences sequences = new Sequences();
        sequences.setSeqName(seqName);
        int count = (int) oracleSequenceMapper.containsSequence(sequences, null);
        return 1 == count;
    }

    /**
     * 获取当前所有序列
     *
     * @return Sequences
     */
    public List<Sequences> getSequences() {
        String user = null;
        if (dataSource instanceof DruidDataSource) {
            user = ((DruidDataSource) dataSource).getUsername();
        }
        return oracleSequenceMapper.getSequences(user);

    }

    /**
     * 获取当前所有序列
     *
     * @return List
     */
    public List<Sequences> getSequences(String seqName) {
        String user = null;
        if (dataSource instanceof DruidDataSource) {
            user = ((DruidDataSource) dataSource).getUsername();
        }
        return oracleSequenceMapper.getSequences(user);
    }
}
